<template>
  <dd-container>
    <dd-card>
      <!-- 数据信息 -->
      <dd-table ref="menuTable"
                rowKey="id"
                :data="tableData"
                :option="option"
                :screen="searchForm"
                :loadingData="loadMenuList"
                :treeProps="{children: 'children', hasChildren: 'hasChildren'}">
        <!-- 占位用的，解决展开收起跑到左边去的问题 -->
        <template slot="condition">
          <el-form-item></el-form-item>
        </template>
        <template slot="operation">
          <el-form-item>
            <el-button type="add" size="small" @click="openDialog('add', {type:1, category: 0, number: 1})" v-if="showButton($route.path, '新增')">新增</el-button>
          </el-form-item>
          <el-form-item>
            <dd-file-upload-text
              :fileList="[]"
              :uploadRequest="uploadImage"
              :onRemoveFile="handleRemoveFile"
              :previewFileUrlList="[]"
              :isPreview="false"
              :showFileList="false"
              :buttonType="'edit'"
              :buttonName="'导入'"
              v-if="showButton($route.path, '导入')">
            </dd-file-upload-text>
          </el-form-item>
          <el-form-item>
            <el-button type="success" size="small" @click="exportExcel()" v-if="showButton($route.path, '导出')">导出</el-button>
          </el-form-item>
        </template>
        <el-table-column prop="cname" label="菜单名称" width="180" align="start" :show-overflow-tooltip="true"></el-table-column>
        <el-table-column prop="parentTxt" label="父菜单" width="230" align="start" :show-overflow-tooltip="true"></el-table-column>
        <el-table-column prop="rname" label="路由名称" width="120" align="start" :show-overflow-tooltip="true"></el-table-column>
        <el-table-column prop="route" label="路由路径" width="230" align="start" :show-overflow-tooltip="true"></el-table-column>
        <el-table-column label="操作" align="center" width="350" fixed="right">
          <template slot-scope="scope">
            <el-button size="mini" :type="scope.row.category==2 ? 'add' : 'add' "  :disabled="scope.row.category==2"
              @click="openDialog('subAdd', scope.row)" v-if="showButton($route.path, '添加子菜单')">添加子菜单
            </el-button>
            <el-button size="mini" type="info" @click="openDialog('info', scope.row)" v-if="showButton($route.path, '详情')">详情</el-button>
            <el-button size="mini" type="edit" @click="openDialog('edit', scope.row)" v-if="showButton($route.path, '编辑')">编辑</el-button>
            <el-button size="mini" type="del" @click="handleDelete(scope.$index, scope.row)" v-if="showButton($route.path, '删除')">删除</el-button>
          </template>
        </el-table-column>
      </dd-table>
      <MenuMgrHandleDialog :visible.sync="menuMgrHandleDialogVisible"
                           :modelType="modelType"
                           :modelData="modelData"
                           :allMenuList="allMenuList"
                           :treeMenuList="treeMenuList"
                           :allInterfaceList="allInterfaceList"
                           :treeInterfaceList="treeInterfaceList"
                           @loadList="loadMenuList"
                           @loadAllList="loadAllMenuList">
      </MenuMgrHandleDialog>
    </dd-card>
  </dd-container>
</template>

<script>
import MenuMgrHandleDialog from './dialog/menuMgrHandleDialog.vue'
import util from '@/libs/util'
import { mapGetters } from 'vuex'

export default {
  name: 'menuMgr',
  components: { MenuMgrHandleDialog },
  data() {
    return {
      searchForm: {
        cname: '',
        pageIndex: 1,
        pageSize: 10,
      },
      selectParent: [],
      tableData: [],
      option: {
        total: 0,
        loading: true,
        operation: true,
      },
      allMenuList: [],
      treeMenuList: [],
      allInterfaceList: [],
      treeInterfaceList: [],
      menuMgrHandleDialogVisible: false,
      modelType: '',
      modelData: {},
    }
  },
  computed: {
    ...mapGetters('ddAdmin/menu', ['showButton'])
  },
  async mounted() {
    await this.loadAllMenuList();
    this.loadInterfaceList();
    this.loadMenuList();
  },
  watch: {
    selectParent(val) {
      if (val.length == 0) {
        this.searchForm.parent = '';
      } else {
        this.searchForm.parent = val[val.length - 1];
      }
    }
  },
  methods: {
    onSearch() {
      this.searchForm.pageIndex = this.$options.data().searchForm.pageIndex;
      this.loadMenuList();
    },
    // 切分树状菜单列表
    async loadMenuList() {
      try {
        let allTreeData = {}, result = {};
        // 一次性获取所有数据
        result = await this.$api.menu.findMenuList({ ...this.searchForm, pageIndex: 1, pageSize: 9999 });
        // 生成父菜单及路由
        result.value.forEach(element => {
          if (element.pid == '' || element.pid == undefined) {
            element['parentTxt'] = '/';
            element['route'] = '/';
            element['rname'] = '';
          } else {
            element['parentTxt'] = this.findParent(element);
            element['route'] = this.findRoute(element);
          }
          if (!element.number) {
            element.number = 1;
          }
        });
        // 生成菜单树
        allTreeData = util.menuTree(result.value);
        // 分页数量
        this.option.total = allTreeData.length;
        // 页数据
        this.tableData = allTreeData.slice((this.searchForm.pageIndex - 1) * this.searchForm.pageSize, (this.searchForm.pageIndex - 1) * this.searchForm.pageSize + this.searchForm.pageSize);
        this.option.loading = false;
      } catch (error) {
        console.log(error);
        this.option.loading = false;
      }
    },
    // 加载所有菜单列表
    async loadAllMenuList() {
      try {
        // 查询所有菜单
        let param = {
          pageIndex: 1,
          pageSize: 9999
        }
        let result = await this.$api.menu.findMenuList(param);
        this.allMenuList = result.value;
        // 处理菜单树型结构
        this.treeMenuList = util.menuTree(result.value);
      } catch (error) {
        console.log(error);
      }
    },
    // 查询父菜单名称
    findParent(res) {
      var txt = '', arr = [], _this = this;
      // 递归找父菜单名称
      function find(pid) {
        _this.allMenuList.forEach(element => {
          // 找菜单名称
          if (element.id == pid) {
            arr.unshift(element.cname)
            if (element.pid) {
              find(element.pid);
            }
          }
        });
      }
      // 查询父菜单名称
      find(res.pid);
      txt = arr.join('/');
      return '/' + txt;
    },
    // 生成菜单路由
    findRoute(res){
      var arr = [], _this = this;
      // 递归找父菜单路由
      function find(pid) {
        _this.allMenuList.forEach(element => {
          // 找菜单路由
          if (element.id == pid) {
            // 压入栈
            arr.unshift(element.rname)
            if (element.pid) {
              find(element.pid);
            }
          }
        });
      }
      // 查询父菜单名称
      find(res.pid);
      var txt = arr.join('/');
      return txt + '/' + res.rname;
    },
    findChildren(res) {
      const idsArr = [];
      // 递归找子菜单id
      function find(item) {
        idsArr.push(item.id);
        if (item.children) {
          item.children.forEach(element => {
            find(element);
          })
        }
      }
      find(res);
      return idsArr;
    },
    // 加载接口列表
    async loadInterfaceList() {
      try {
        // 查询所有接口
        let param = {
          pageIndex: 1,
          pageSize: 9999
        }
        let result = await this.$api.right.findRightList(param);
        this.allInterfaceList = result.value;
        // 接口模块树
        this.treeInterfaceList = this.handleTreeData(result.value);
      } catch (error) {
        console.log(error);
      }
    },
    // 接口数据处理
    handleTreeData(list) {
      var map = {}, dest = [];
      for (var i = 0, iLen = list.length; i < iLen; i++) {
        let currNode = list[i];
        let childrenNodes = {
          id: list[i].id,
          name: list[i].name,
          label: list[i].description,
        }
        // 按模块划分
        if (!map[currNode.module]) {
          // 添加到模块数组中
          dest.push({
            name: currNode.module,
            label: currNode.moduleName,
            children: [],
          })
          // 模块添加接口信息
          dest[dest.length - 1].children.push(childrenNodes);
          // 生成新的模块
          map[currNode.module] = currNode;
        } else {
          // 追加到已有模块中
          for (var j = 0, jLen = dest.length; j < jLen; j++) {
            var destItem = dest[j];
            if (destItem.name == currNode.module) {
              destItem.children.push(childrenNodes);
              break;
            }
          }
        }
      }
      return dest;
    },
    openDialog(modelType, modelData) {
      this.modelType = modelType;
      this.modelData = modelData === undefined ? {} : JSON.parse(JSON.stringify(modelData));
      console.log(this.modelData);
      this.menuMgrHandleDialogVisible = true;
    },
    exportExcel(){
      this.$api.menu
            .export({})
            .then(res => {
              util.fileDownloadBlob(res, '系统菜单表')
              this.$message.success("导出系统菜单表成功！");
            });
    },
    handleDelete(index, row) {
      let ids = this.findChildren(row),_this = this;
      this.$confirm(`此操作将永久删除 ${row.cname} 菜单, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        beforeClose(action, instance, done) {
          if (action == 'confirm') {
            this.$api.menu
              .delBatchMenu({ ids })
              .then((res) => {
                this.$message.success('删除成功');
                done();
                _this.loadAllMenuList();
                _this.loadMenuList();
              })
              .catch((error) => {
                console.log(error);
              });
          } else {
            done();
          }
        },
      })
      .then(() => { })
      .catch((err) => {
        this.$message.info('已取消删除');
      });
    },
    // 上传图片
    uploadImage(upFormData) {
      this.$api.menu
          .import(upFormData)
    },
    // 图片删除回调函数
    handleRemoveFile(file, pictureList) {
      console.log('file', file);
      console.log('pictureList', pictureList);
    }
  },
}
</script>
<style lang="scss" scoped>

</style>
